From 8bced8601696af0359c2002fa138441a7de970d0 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 20 Jul 2010 13:42:17 +0100 Subject: [PATCH] hvmloader: clear the xenbus event-channel when we're done with it. Otherwise a later xenbus client that naively waits for the rising edge could get stuck. Signed-off-by: Tim Deegan --- tools/firmware/hvmloader/util.c | 30 ++++++++++++++++++++---------- tools/firmware/hvmloader/util.h | 3 +++ tools/firmware/hvmloader/xenbus.c | 14 ++++++++++---- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 1467d5ca7e..fe561a4f99 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -587,10 +587,28 @@ struct hvm_info_table *get_hvm_info_table(void) return table; } -uint16_t get_cpu_mhz(void) +struct shared_info *get_shared_info(void) { + static struct shared_info *shared_info = NULL; struct xen_add_to_physmap xatp; - struct shared_info *shared_info = (struct shared_info *)0xfffff000; + + if ( shared_info != NULL ) + return shared_info; + + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_shared_info; + xatp.idx = 0; + xatp.gpfn = 0xfffffu; + shared_info = (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) + BUG(); + + return shared_info; +} + +uint16_t get_cpu_mhz(void) +{ + struct shared_info *shared_info = get_shared_info(); struct vcpu_time_info *info = &shared_info->vcpu_info[0].time; uint64_t cpu_khz; uint32_t tsc_to_nsec_mul, version; @@ -600,14 +618,6 @@ uint16_t get_cpu_mhz(void) if ( cpu_mhz != 0 ) return cpu_mhz; - /* Map shared-info page. */ - xatp.domid = DOMID_SELF; - xatp.space = XENMAPSPACE_shared_info; - xatp.idx = 0; - xatp.gpfn = (unsigned long)shared_info >> 12; - if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) - BUG(); - /* Get a consistent snapshot of scale factor (multiplier and shift). */ do { version = info->version; diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index b5a84fd177..3c661360b2 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -69,6 +69,9 @@ void pci_write(uint32_t devfn, uint32_t reg, uint32_t len, uint32_t val); #define pci_writew(devfn, reg, val) (pci_write(devfn, reg, 2, (uint16_t)val)) #define pci_writel(devfn, reg, val) (pci_write(devfn, reg, 4, (uint32_t)val)) +/* Get a pointer to the shared-info page */ +struct shared_info *get_shared_info(void); + /* Get CPU speed in MHz. */ uint16_t get_cpu_mhz(void); diff --git a/tools/firmware/hvmloader/xenbus.c b/tools/firmware/hvmloader/xenbus.c index aad8a441bb..e980e47bef 100644 --- a/tools/firmware/hvmloader/xenbus.c +++ b/tools/firmware/hvmloader/xenbus.c @@ -53,14 +53,20 @@ void xenbus_setup(void) (unsigned long) rings, (unsigned long) event); } -/* Reset the xenbus connection so the next kernel can start again. - * We zero out the whole ring -- the backend can handle this, and it's - * not going to surprise any frontends since it's equivalent to never - * having used the rings. */ +/* Reset the xenbus connection so the next kernel can start again. */ void xenbus_shutdown(void) { ASSERT(rings != NULL); + + /* We zero out the whole ring -- the backend can handle this, and it's + * not going to surprise any frontends since it's equivalent to never + * having used the rings. */ memset(rings, 0, sizeof *rings); + + /* Clear the xenbus event-channel too */ + get_shared_info()->evtchn_pending[event / sizeof (unsigned long)] + &= ~(1UL << ((event % sizeof (unsigned long)))); + rings = NULL; } -- 2.30.2